#include <iostream>
#include <noise.h>

#include "noiseutils.h"
#include "../MathUtil.h"

using namespace noise;

#define PLAINS		1
#define FORREST		2
#define MOUNTAINS	3
#define DESERT		4
#define SWAMP		5
#define TAIGA		6
#define JUNGLE		7

inline WCHAR * BiomeToStr(BYTE biome) {
	switch (biome)
	{
	case PLAINS:
		return L"PLAINS";
	case FORREST:
		return L"FORREST";
	case MOUNTAINS:
		return L"MOUNTAINS";
	case DESERT:
		return L"DESERT";
	case SWAMP:
		return L"SWAMP";
	case TAIGA:
		return L"TAIGA";
	case JUNGLE:
		return L"JUNGLE";
	default:
		return L"NONE";
	}

}

class Biomemap 
{
private:
	int	  _x;
	int	  _z;

	module::Perlin				pGen1, pGen2;

	utils::NoiseMap				TemperatureMap;
	utils::NoiseMapBuilderPlane TemperatureMapBuilder;

	utils::NoiseMap				HumidityMap;
	utils::NoiseMapBuilderPlane HumidityMapBuilder;

protected:
	void init(int seed, int x, int z);
public:
	Biomemap(int seed, int x, int z);

	float getHumidity(int x, int z);
	float getTemperatur(int x, int z);
	BYTE  getBiome(int x, int z);
};


inline D3DXVECTOR3 BiomeColor(float t, float h) {
	float d  = clamp(((t - h) - 1.05f) * 5.0f, 0.0f, 1.0f);//clamp((t - 0.65f) * 10.0f, 0.0f, 1.0f) * clamp((-h - 0.040f) * 10.0f, 0.0f, 1.0f);
	float j  = clamp(((t + h) - 1.05f) * 5.0f, 0.0f, 1.0f);//clamp((t - 0.65f) * 10.0f, 0.0f, 1.0f) * clamp((h - 0.040f) * 10.0f, 0.0f, 1.0f);

	float s  = clamp((h - 0.65f) * 5.0f, 0.0f, 1.0f - j);//1.0f - (4*t*t)
	float i  = clamp((-t - 0.65f) * 5.0f, 0.0f, 1.0f);
	float n  = clamp(1.0f - (j + d + s + i), 0.0f, 1.0f);

	/*
	 if ( h > 0.6f ) {
		float j = clamp((t - 0.80f), 0.0f, 1.0f);
		float s = clamp((0.80f - t), 0.0f, 1.0f);

		g -= min(0.7f,(h - 0.6f) * s * 10.0f);
		r -= min(0.2f,(h - 0.6f) * s * 10.0f);
		b -= min(0.1f,(h - 0.6f) * s * 10.0f);

		//g += min(0.7f,(h - 0.6f) * j * 50.0f);
		r -= min(0.3f,(h - 0.6f) * j * 50.0f);
		b -= min(0.2f,(h - 0.6f) * j * 50.0f);
	} else if (t > 0.55f ) {
		float j = clamp((h - 0.3f), 0.0f, 1.0f);
		float d = clamp((0.3f - h), 0.0f, 1.0f);

		r += min(0.6f,(t - 0.55f) * d * 10.0f);

		r -= min(0.3f,(t - 0.55f) * j * 10.0f);
		b -= min(0.2f,(t - 0.55f) * j * 10.0f);
	} else if ( t < -0.6f ) {
		g -= min(0.7f,-(t + 0.6f) * 1.7f);
		r -= min(0.2f,-(t + 0.6f) * 0.3f);
		b -= min(0.2f,-(t + 0.6f) * 0.3f);
	} /*else if ( h > 0.6f ) {
		g -= min(0.7f,(h - 0.6f) * 1.7f);
		r -= min(0.2f,(h - 0.6f) * 0.3f);
		b -= min(0.1f,(h - 0.6f) * 0.3f);
	}*/
	return (D3DXVECTOR3(0.1f, 1.0f, 0.1f) * j) + (D3DXVECTOR3(0.8f, 0.7f, 0.2f) * d) + (D3DXVECTOR3(0.2f, 0.5f, 0.2f) * (s+i)) + (D3DXVECTOR3(0.2f, 01.0f, 0.3f) * n);//D3DXVECTOR3(r, g, b);
};